package com.wingice.system.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wingice.spring.security.common.utils.SecurityUtils;
import com.wingice.spring.security.model.KnifeUser;
import com.wingice.system.constant.SecurityConstant;
import com.wingice.system.entity.SysResource;
import com.wingice.system.entity.SysRole;
import com.wingice.system.entity.SysRoleResource;
import com.wingice.system.exception.SysBusinessCode;
import com.wingice.system.exception.SysBusinessException;
import com.wingice.system.mapper.SysRoleResourceMapper;
import com.wingice.system.service.SysResourceService;
import com.wingice.system.service.SysRoleResourceService;
import com.wingice.system.service.SysRoleService;
import com.wingice.system.service.SysRoleUserService;
import com.wingice.system.vo.UserRoleResourceVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色-资源关联 服务实现类
 * </p>
 *
 * @author 胡昊
 * @since 2020-07-23
 */
@Transactional
@Service
public class SysRoleResourceServiceImpl extends ServiceImpl<SysRoleResourceMapper, SysRoleResource> implements SysRoleResourceService {

    @Resource
    private SysResourceService sysResourceService;
    @Resource
    private SysRoleUserService sysRoleUserService;
    @Resource
    private SysRoleResourceService sysRoleResourceService;
    @Resource
    private SysRoleService sysRoleService;

    @Override
    public Boolean saveRoleResource(UserRoleResourceVo userRoleResourceVo) {
        //获取当前用户有权限的资源
        final KnifeUser knifeUser = SecurityUtils.getUser();
        final List<SysRole> userRoleList = sysRoleUserService.listUserRole(knifeUser.getId());
        final SysRole superAdminRole = sysRoleService.getOne(Wrappers.<SysRole>lambdaQuery().eq(SysRole::getRoleKey, SecurityConstant.KNIFE_SUPER_ADMIN));
        final List<SysResource> sysResourceList = listUserResource(knifeUser.getId());
        if (!userRoleList.contains(superAdminRole) && !sysResourceList.stream().map(SysResource::getId).collect(Collectors.toList()).containsAll(userRoleResourceVo.getResourceIdList())) {
            throw new SysBusinessException(SysBusinessCode.RESOURCE_PERMISSION_DENY);
        }
        //找出现有关联
        final List<SysRoleResource> sysRoleResourceList = list(Wrappers.<SysRoleResource>lambdaQuery().eq(SysRoleResource::getRoleId, userRoleResourceVo.getRoleId()));
        //处理删除的
        final List<String> deleteIdList = sysRoleResourceList.stream()
                .filter(sysRoleResource -> !userRoleResourceVo.getResourceIdList().contains(sysRoleResource.getResourceId()))
                .map(SysRoleResource::getId)
                .collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(deleteIdList)) {
            removeByIds(deleteIdList);
        }
        //处理新增的
        final List<String> resourceIdList = sysRoleResourceList.stream().map(SysRoleResource::getResourceId).collect(Collectors.toList());
        final List<String> resourceIdListNew = userRoleResourceVo.getResourceIdList().stream()
                .filter(id -> !resourceIdList.contains(id))
                .collect(Collectors.toList());
        final List<SysRoleResource> sysRoleResourceListNew = new ArrayList<>();
        resourceIdListNew.forEach(id -> {
            final SysRoleResource sysRoleResource = new SysRoleResource();
            sysRoleResource.setRoleId(userRoleResourceVo.getRoleId());
            sysRoleResource.setResourceId(id);
            sysRoleResourceListNew.add(sysRoleResource);
        });
        return saveBatch(sysRoleResourceListNew);
    }

    @Override
    public List<SysResource> listRoleResource(String roleId) {
        final List<String> resourceIdList = list(Wrappers.<SysRoleResource>lambdaQuery().eq(SysRoleResource::getRoleId, roleId))
                .stream()
                .map(SysRoleResource::getResourceId)
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(resourceIdList)) {
            return Collections.emptyList();
        }
        return sysResourceService.listByIds(resourceIdList);
    }

    public List<SysResource> listUserResource(String userId) {
        final List<SysRole> sysRoleList = sysRoleUserService.listUserRole(userId);
        if (CollectionUtils.isEmpty(sysRoleList)) {
            return Collections.emptyList();
        }
        final List<SysRoleResource> sysRoleResourceList = sysRoleResourceService.list(Wrappers.<SysRoleResource>lambdaQuery().in(SysRoleResource::getRoleId, sysRoleList.stream().map(SysRole::getId).collect(Collectors.toList())));
        if (CollectionUtils.isEmpty(sysRoleResourceList)) {
            return Collections.emptyList();
        }
        return sysResourceService.listByIds(sysRoleResourceList.stream().map(SysRoleResource::getResourceId).collect(Collectors.toList()));
    }
}
